package com.wyh.utils.feemanagementutils;

import cn.hutool.core.date.DateTime;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import com.itextpdf.text.pdf.draw.LineSeparator;
import com.wyh.domain.dto.feemanagementdto.BillDTO;
import com.wyh.domain.dto.feemanagementdto.ExpenseDetails;
import com.wyh.domain.dto.feemanagementdto.ReceiptDTO;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.List;

@Slf4j
public class PdfUtil {

    public static void setResponseContentType(HttpServletResponse response, String fileName) throws UnsupportedEncodingException {
        response.setContentType("application/pdf");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "utf-8") + ".pdf");
        response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
    }

    public static void downloadPdf(List<ExpenseDetails> expenseDetailsList, String noticenumber, Date timeym, String remarks, ReceiptDTO receiptDTO, HttpServletResponse response) {
        // 定义全局的字体静态变量
        Font titlefont;
        Font headfont = null;
        Font keyfont = null;
        Font textfont = null;
        Font content = null;
        Font space = null;
        Font space1 = null;
        Font space2 = null;
        Font space3 = null;
        // 最大宽度
        try {
            // 不同字体（这里定义为同一种字体：包含不同字号、不同style）
            BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            titlefont = new Font(bfChinese, 16, Font.BOLD);
            headfont = new Font(bfChinese, 10, Font.BOLD);
            keyfont = new Font(bfChinese, 22, Font.BOLD);
            textfont = new Font(bfChinese, 10, Font.NORMAL);
            content = new Font(bfChinese, 10, Font.NORMAL);
            space = new Font(bfChinese, 5, Font.NORMAL);
            space1 = new Font(bfChinese, 20, Font.NORMAL);
            space2 = new Font(bfChinese, 20, Font.NORMAL);
            space3 = new Font(bfChinese, 3, Font.NORMAL);

        } catch (Exception e) {
            e.printStackTrace();
        }
        BaseFont bf;
        Font font = null;
        try {
            //创建字体
            bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            //使用字体并给出颜色
            font = new Font(bf, 20, Font.BOLD, BaseColor.BLACK);
        } catch (Exception e) {
            e.printStackTrace();
        }

        Document document = new Document(new RectangleReadOnly(842F, 595F));
        //设置页边距  60:左边距，60：右边距，72：上边距，72：下边距
        document.setMargins(60, 60, 72, 72);
        try {
            PdfWriter writer = null;
            try {
                try {
                    writer = PdfWriter.getInstance(document, response.getOutputStream());
                } catch (DocumentException e) {
                    e.printStackTrace();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            //添加页码
            writer.setPageEvent(new PdfPageUtil());
            //打开生成的pdf文件
            document.open();
            //设置内容
            Paragraph paragraph = new Paragraph("重庆中链融科技有限公司缴费账单", font);
            paragraph.setAlignment(1);
            //引用字体
            try {
                document.add(paragraph);
            } catch (DocumentException e) {
                e.printStackTrace();
            }

            // 设置表格的列宽和列数
            float[] widths = {25f, 25f, 25f, 25f, 25f, 25f};
            PdfPTable table = new PdfPTable(widths);
            table.setSpacingBefore(20f);
            // 设置表格宽度为100%
            table.setWidthPercentage(100.0F);
            table.setHeaderRows(1);
            table.getDefaultCell().setHorizontalAlignment(1);
            PdfPCell cell = null;

            // 设置表格的列宽和列数
            float[] widths1 = {25f, 25f, 25f, 25f, 25f, 25f, 25f, 25f, 25f, 25f, 25f};
            PdfPTable table1 = new PdfPTable(widths1);
            table1.setSpacingBefore(20f);
            // 设置表格宽度为100%
            table1.setWidthPercentage(100.0F);
            table1.setHeaderRows(1);
            table1.getDefaultCell().setHorizontalAlignment(1);

            // 插入 "费用明细" 行
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年M月");
            String formattedTime = dateFormat.format(timeym);
            PdfPCell cell2020Fee = new PdfPCell(new Paragraph(formattedTime + "费用明细", content));
            cell2020Fee.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell2020Fee.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell2020Fee.setColspan(11); // 设置跨列数，与表格列数一致
            table1.addCell(cell2020Fee);

            //人员列表-第四行
            cell = new PdfPCell(new Paragraph("楼栋", content));
            cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell.setFixedHeight(20);
            table1.addCell(cell);

            cell = new PdfPCell(new Paragraph("楼层编号", content));
            cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            table1.addCell(cell);

            cell = new PdfPCell(new Paragraph("费用分类", content));
            cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            table1.addCell(cell);

            cell = new PdfPCell(new Paragraph("收费项目名称", content));
            cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            table1.addCell(cell);

            cell = new PdfPCell(new Paragraph("起度", content));
            cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            table1.addCell(cell);

            cell = new PdfPCell(new Paragraph("止度", content));
            cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            table1.addCell(cell);

            cell = new PdfPCell(new Paragraph("表倍率", content));
            cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            table1.addCell(cell);

            cell = new PdfPCell(new Paragraph("数量", content));
            cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            table1.addCell(cell);

            cell = new PdfPCell(new Paragraph("单价", content));
            cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            table1.addCell(cell);

            cell = new PdfPCell(new Paragraph("应收金额", content));
            cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            table1.addCell(cell);

            cell = new PdfPCell(new Paragraph("欠收金额", content));
            cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            table1.addCell(cell);

            //人员列表数据-第五行
            double totalAccountsReceivable = 0.0;
            double totalOutstandingAmount = 0.0;

            if (expenseDetailsList.size() > 0) {
                for (ExpenseDetails expenseDetails : expenseDetailsList) {
                    PdfPCell cell1 = new PdfPCell(new Paragraph(expenseDetails.getBuildingunitsname(), content)); // 假设这里使用 customername 字段
                    PdfPCell cell2 = new PdfPCell(new Paragraph(expenseDetails.getLayername(), content)); // 假设这里使用 propertyname 字段
                    PdfPCell cell3 = new PdfPCell(new Paragraph(expenseDetails.getName(), content)); // 假设这里使用 bid 字段
                    PdfPCell cell4 = new PdfPCell(new Paragraph(expenseDetails.getBillingitemsname(), content)); // 假设这里使用 account 字段
                    PdfPCell cell5 = new PdfPCell(new Paragraph(expenseDetails.getPreviousreading(), content));
                    PdfPCell cell6 = new PdfPCell(new Paragraph(expenseDetails.getCurrentreading(), content));
                    PdfPCell cell7 = new PdfPCell(new Paragraph(String.valueOf(expenseDetails.getMultiplier()), content));
                    PdfPCell cell8 = new PdfPCell(new Paragraph(String.valueOf(expenseDetails.getDosage()), content));
                    PdfPCell cell9 = new PdfPCell(new Paragraph(expenseDetails.getPrice(), content));
                    PdfPCell cell10 = new PdfPCell(new Paragraph(expenseDetails.getAccountsreceivable(), content));
                    PdfPCell cell11 = new PdfPCell(new Paragraph(expenseDetails.getOutstandingamount(), content));

                    totalAccountsReceivable += Double.parseDouble(expenseDetails.getAccountsreceivable());
                    totalOutstandingAmount += Double.parseDouble(expenseDetails.getOutstandingamount());

                    cell1.setVerticalAlignment(Element.ALIGN_MIDDLE);
                    cell1.setHorizontalAlignment(Element.ALIGN_CENTER);
                    cell2.setVerticalAlignment(Element.ALIGN_MIDDLE);
                    cell2.setHorizontalAlignment(Element.ALIGN_CENTER);
                    cell3.setVerticalAlignment(Element.ALIGN_MIDDLE);
                    cell3.setHorizontalAlignment(Element.ALIGN_CENTER);
                    cell4.setVerticalAlignment(Element.ALIGN_MIDDLE);
                    cell4.setHorizontalAlignment(Element.ALIGN_CENTER);
                    cell5.setVerticalAlignment(Element.ALIGN_MIDDLE);
                    cell5.setHorizontalAlignment(Element.ALIGN_CENTER);
                    cell6.setVerticalAlignment(Element.ALIGN_MIDDLE);
                    cell6.setHorizontalAlignment(Element.ALIGN_CENTER);
                    cell7.setVerticalAlignment(Element.ALIGN_MIDDLE);
                    cell7.setHorizontalAlignment(Element.ALIGN_CENTER);
                    cell8.setVerticalAlignment(Element.ALIGN_MIDDLE);
                    cell8.setHorizontalAlignment(Element.ALIGN_CENTER);
                    cell9.setVerticalAlignment(Element.ALIGN_MIDDLE);
                    cell9.setHorizontalAlignment(Element.ALIGN_CENTER);
                    cell10.setVerticalAlignment(Element.ALIGN_MIDDLE);
                    cell10.setHorizontalAlignment(Element.ALIGN_CENTER);
                    cell11.setVerticalAlignment(Element.ALIGN_MIDDLE);
                    cell11.setHorizontalAlignment(Element.ALIGN_CENTER);

                    table1.addCell(cell1);
                    table1.addCell(cell2);
                    table1.addCell(cell3);
                    table1.addCell(cell4);
                    table1.addCell(cell5);
                    table1.addCell(cell6);
                    table1.addCell(cell7);
                    table1.addCell(cell8);
                    table1.addCell(cell9);
                    table1.addCell(cell10);
                    table1.addCell(cell11);
                }
            }

            // 添加合计标签单元格
            PdfPCell totalLabelCell = new PdfPCell(new Paragraph("合计", content));
            totalLabelCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
            totalLabelCell.setHorizontalAlignment(Element.ALIGN_CENTER);
            totalLabelCell.setColspan(9);  // 跨越合计金额和应收金额之前的列数
            table1.addCell(totalLabelCell);

            // 添加合计金额单元格
            PdfPCell totalAmountCell = new PdfPCell(new Paragraph(String.valueOf(totalAccountsReceivable), content));
            totalAmountCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
            totalAmountCell.setHorizontalAlignment(Element.ALIGN_CENTER);
            table1.addCell(totalAmountCell);

            // 添加应收金额单元格
            PdfPCell totalArrearsCell = new PdfPCell(new Paragraph(String.valueOf(totalOutstandingAmount), content));
            totalArrearsCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
            totalArrearsCell.setHorizontalAlignment(Element.ALIGN_CENTER);
            table1.addCell(totalArrearsCell);

            // 获取当前时间并格式化
            DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");
            LocalDateTime now = LocalDateTime.now();
            String formattedTimes = dtf.format(now);

            // 生成时间和通知单编号
            try {
                document.add(new Paragraph("\n"));
            } catch (DocumentException e) {
                e.printStackTrace();
            }
            Paragraph p = new Paragraph();
            p.add(new Chunk("生成时间: " + formattedTimes, content));
            p.add(new Chunk("                                                                                                                                 ")); // 增加水平间隔
            p.add(new Chunk("通知单编号: " + noticenumber, content));
            try {
                document.add(p);
            } catch (DocumentException e) {
                e.printStackTrace();
            }

            // 添加 table1 到文档
            try {
                document.add(table1);
            } catch (DocumentException e) {
                e.printStackTrace();
            }


            // 按收费项目名称分别汇总应收金额和欠收金额
            Map<String, BigDecimal> receivableTotals = new HashMap<>();
            Map<String, BigDecimal> outstandingTotals = new HashMap<>();

            BigDecimal totalReceivable = BigDecimal.ZERO;
            BigDecimal totalOutstanding = BigDecimal.ZERO;

            for (ExpenseDetails expenseDetails : expenseDetailsList) {
                String chargeItem = expenseDetails.getBillingitemsname();
                BigDecimal accountsReceivable = new BigDecimal(expenseDetails.getAccountsreceivable());
                BigDecimal outstandingAmount = new BigDecimal(expenseDetails.getOutstandingamount());

                // 添加应收金额
                receivableTotals.put(chargeItem, receivableTotals.getOrDefault(chargeItem, BigDecimal.ZERO)
                        .add(accountsReceivable));
                totalReceivable = totalReceivable.add(accountsReceivable);

                // 添加欠收金额
                outstandingTotals.put(chargeItem, outstandingTotals.getOrDefault(chargeItem, BigDecimal.ZERO)
                        .add(outstandingAmount));
                totalOutstanding = totalOutstanding.add(outstandingAmount);
            }

            // 添加 table2 到文档
            PdfPTable table2 = new PdfPTable(3);
            table2.setSpacingBefore(10f);
            table2.setWidthPercentage(100.0F);
            float[] columnWidths = {33f, 33f, 34f}; // 列宽比例
            try {
                table2.setWidths(columnWidths);
            } catch (DocumentException e) {
                e.printStackTrace();
            }

            // 添加费用汇总的标题行
            PdfPCell cell2021Fee = new PdfPCell(new Paragraph(formattedTime + "费用合计", content));
            cell2021Fee.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell2021Fee.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell2021Fee.setColspan(3);
            table2.addCell(cell2021Fee);

            PdfPCell cellChargeItem = new PdfPCell(new Paragraph("收费项目", content));
            cellChargeItem.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cellChargeItem.setHorizontalAlignment(Element.ALIGN_CENTER);
            table2.addCell(cellChargeItem);

            PdfPCell cellReceivableAmount = new PdfPCell(new Paragraph("应收金额", content));
            cellReceivableAmount.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cellReceivableAmount.setHorizontalAlignment(Element.ALIGN_CENTER);
            table2.addCell(cellReceivableAmount);

            PdfPCell cellOutstandingAmount = new PdfPCell(new Paragraph("欠收金额", content));
            cellOutstandingAmount.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cellOutstandingAmount.setHorizontalAlignment(Element.ALIGN_CENTER);
            table2.addCell(cellOutstandingAmount);

            // 填充 table2，显示汇总的收费项目数据
            for (Map.Entry<String, BigDecimal> entry : receivableTotals.entrySet()) {
                PdfPCell itemCell = new PdfPCell(new Paragraph(entry.getKey(), content));
                itemCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
                itemCell.setHorizontalAlignment(Element.ALIGN_CENTER);
                table2.addCell(itemCell);

                PdfPCell receivableCell = new PdfPCell(new Paragraph(entry.getValue().toString(), content));
                receivableCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
                receivableCell.setHorizontalAlignment(Element.ALIGN_CENTER);
                table2.addCell(receivableCell);

                // 添加对应的欠收金额单元格
                BigDecimal outstandingAmount = outstandingTotals.getOrDefault(entry.getKey(), BigDecimal.ZERO);
                PdfPCell outstandingCell = new PdfPCell(new Paragraph(outstandingAmount.toString(), content));
                outstandingCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
                outstandingCell.setHorizontalAlignment(Element.ALIGN_CENTER);
                table2.addCell(outstandingCell);
            }

            // 添加合计标签单元格
            PdfPCell totalLabelCell2 = new PdfPCell(new Paragraph("合计", content));
            totalLabelCell2.setVerticalAlignment(Element.ALIGN_MIDDLE);
            totalLabelCell2.setHorizontalAlignment(Element.ALIGN_CENTER);
            totalLabelCell2.setColspan(1);
            table2.addCell(totalLabelCell2);

            // 添加合计金额单元格
            PdfPCell totalReceivableCell = new PdfPCell(new Paragraph(totalReceivable.toString(), content));
            totalReceivableCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
            totalReceivableCell.setHorizontalAlignment(Element.ALIGN_CENTER);
            table2.addCell(totalReceivableCell);

            // 添加欠收金额单元格
            PdfPCell totalOutstandingCell = new PdfPCell(new Paragraph(totalOutstanding.toString(), content));
            totalOutstandingCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
            totalOutstandingCell.setHorizontalAlignment(Element.ALIGN_CENTER);
            table2.addCell(totalOutstandingCell);

            // 将 table2 添加到文档中
            try {
                document.add(table2);
            } catch (DocumentException e) {
                e.printStackTrace();
            }

            try {
                document.add(new Paragraph("\n"));
            } catch (DocumentException e) {
                e.printStackTrace();
            }
            try {
                document.add(new Chunk(new LineSeparator()));
            } catch (DocumentException e) {
                e.printStackTrace();
            }
            try {
                document.add(new Paragraph("\n"));
            } catch (DocumentException e) {
                e.printStackTrace();
            }

            Paragraph paragraph1 = new Paragraph();
            paragraph1.add(new Chunk("备注:", headfont));
            paragraph1.add(new Chunk(remarks, textfont));
            try {
                document.add(paragraph1);
            } catch (DocumentException e) {
                e.printStackTrace();
            }

            try {
                document.add(new Paragraph("\n"));
            } catch (DocumentException e) {
                e.printStackTrace();
            }


            try {
                // 添加收款方信息
                Paragraph payeeParagraph = new Paragraph("收款方: " + receiptDTO.getPayee(), content);
                document.add(payeeParagraph);

                // 添加收款行信息
                Paragraph bankParagraph = new Paragraph("收款行: " + receiptDTO.getOpeningbank(), content);
                document.add(bankParagraph);

                // 添加收款账号信息
                Paragraph accountParagraph = new Paragraph("收款账号: " + receiptDTO.getBankaccount(), content);
                document.add(accountParagraph);

                // 添加收款金额
                Paragraph amountParagraph = new Paragraph("收款金额: " + receiptDTO.getAmount(), content);
                document.add(amountParagraph);

                // 添加打款备注
                Paragraph remarkParagraph = new Paragraph("打款备注: " + receiptDTO.getRemarks(), content);
                document.add(remarkParagraph);

                // 添加水印



                document.close();


            } catch (Exception e) {
                log.error("error", e);
            } finally {
                document.close();
            }
        } finally {

        }

    }
}
